package com.jjty.dataGenerator.jshjy.service;

import com.jjty.dataGenerator.jshjy.entity.JsAttendanceData;
import com.jjty.dataGenerator.jshjy.entity.JsCallData;
import com.jjty.dataGenerator.jshjy.entity.JsHeartbeatData;
import com.jjty.dataGenerator.jshjy.entity.JsLocationData;
import com.jjty.dataGenerator.jshjy.event.DataInsertEvent;
import com.jjty.dataGenerator.jshjy.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Random;

@Service
@Slf4j
public class EduDataGenerateService {

    @Autowired
    private JsImeiListMapper imeiListMapper;
    @Autowired
    private JsHeartbeatDataMapper heartbeatDataMapper;
    @Autowired
    private JsLocationDataMapper locationDataMapper;
    @Autowired
    private JsCallDataMapper callDataMapper;
    @Autowired
    private JsAttendanceDataMapper attendanceDataMapper;

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    // 渠道编码（由和教育平台提供）
    @Value("${jsedu.channel}")
    private String channel;

    private static final Random random = new Random();
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 生成心跳数据（每日推送接口）
     * @param count 生成数量
     */
    public void generateHeartbeatData(int count) {
        List<String> imeiList = getValidImeiList();
        if (imeiList.isEmpty()) {
            log.error("无有效IMEI号，无法生成心跳数据");
            return;
        }

        for (int i = 0; i < count; i++) {
            JsHeartbeatData data = new JsHeartbeatData();
            //data.setChannel(channel);
            data.setImeiNo(imeiList.get(random.nextInt(imeiList.size())));
            // 最后心跳时间：过去24小时内随机时间
            LocalDateTime lastHeartbeatTime = LocalDateTime.now()
                    .minusHours(random.nextInt(24))
                    .minusMinutes(random.nextInt(60));
            data.setLastHeartbeatTime(lastHeartbeatTime.format(formatter));

            heartbeatDataMapper.insert(data);
            // 发布事件，通知监听器进行推送
            eventPublisher.publishEvent(new DataInsertEvent(this, data));
        }
        log.info("心跳数据生成完成，共{}条", count);
    }

    /**
     * 生成定位数据（实时同步接口）
     * @param count 生成数量
     */
    public void generateLocationData(int count) {
        List<String> imeiList = getValidImeiList();
        if (imeiList.isEmpty()) {
            log.error("无有效IMEI号，无法生成定位数据");
            return;
        }

        for (int i = 0; i < count; i++) {
            JsLocationData data = new JsLocationData();
            //data.setChannel(channel);
            data.setImeiNo(imeiList.get(random.nextInt(imeiList.size())));
            // 定位时间：当前时间
            data.setLocationTime(LocalDateTime.now().format(formatter));
            // 方位坐标：江苏区域（纬度30.5-35.0，经度116.0-122.0）
            double latitude = 30.5 + random.nextDouble() * 4.5;
            double longitude = 116.0 + random.nextDouble() * 6.0;
            data.setPosition(String.format("%.6f,%.6f", latitude, longitude));

            locationDataMapper.insert(data);
            // 发布事件，通知监听器进行推送
            eventPublisher.publishEvent(new DataInsertEvent(this, data));
        }
        log.info("定位数据生成完成，共{}条", count);
    }

    /**
     * 生成通话数据（实时同步接口）
     * @param count 生成数量
     */
    public void generateCallData(int count) {
        List<String> imeiList = getValidImeiList();
        if (imeiList.isEmpty()) {
            log.error("无有效IMEI号，无法生成通话数据");
            return;
        }

        for (int i = 0; i < count; i++) {
            JsCallData data = new JsCallData();
            //data.setChannel(channel);
            data.setImeiNo(imeiList.get(random.nextInt(imeiList.size())));
            // 通话时间：过去12小时内随机时间
            LocalDateTime callTime = LocalDateTime.now()
                    .minusHours(random.nextInt(12))
                    .minusMinutes(random.nextInt(60));
            data.setCallTime(callTime.format(formatter));
            data.setPhoneNo(generatePhoneNumber());
            // 通话时长：10-599秒
            data.setDuration(String.valueOf(10 + random.nextInt(590)));
            // 当月剩余时长：1000-5999秒
            data.setRemainingDuration(String.valueOf(1000 + random.nextInt(5000)));

            callDataMapper.insert(data);
            eventPublisher.publishEvent(new DataInsertEvent(this, data));
        }
        log.info("通话数据生成完成，共{}条", count);
    }

    /**
     * 生成考勤数据（实时同步接口）
     * @param count 生成数量
     */
    public void generateAttendanceData(int count) {
        List<String> imeiList = getValidImeiList();
        if (imeiList.isEmpty()) {
            log.error("无有效IMEI号，无法生成考勤数据");
            return;
        }

        for (int i = 0; i < count; i++) {
            JsAttendanceData data = new JsAttendanceData();
            //data.setChannel(channel);
            data.setImeiNo(imeiList.get(random.nextInt(imeiList.size())));
            // 考勤时间：当前时间
            data.setRecordTime(LocalDateTime.now().format(formatter));
            // 考勤类型：1-进校 2-离校 3-签到 4-宿舍考勤
            data.setType(String.valueOf(1 + random.nextInt(4)));
            // 考勤状态：1-正常（概率较高）、2-迟到、3-早退、4-无效打卡、5-重复打卡
            int[] states = {1, 1, 1, 1, 2, 3, 4, 5};
            data.setState(String.valueOf(states[random.nextInt(states.length)]));

            attendanceDataMapper.insert(data);
            eventPublisher.publishEvent(new DataInsertEvent(this, data));
        }
        log.info("考勤数据生成完成，共{}条", count);
    }

    /**
     * 获取有效IMEI号列表
     */
    private List<String> getValidImeiList() {
        return imeiListMapper.selectValidImeiList();
    }

    /**
     * 生成随机手机号
     */
    private String generatePhoneNumber() {
        String[] prefixes = {"138", "139", "137", "150", "151", "186", "189"};
        String prefix = prefixes[random.nextInt(prefixes.length)];
        StringBuilder suffix = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            suffix.append(random.nextInt(10));
        }
        return prefix + suffix;
    }
}